package com.ruibang.glass.purchase.service.impl;


import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruibang.glass.common.constants.Constants;
import com.ruibang.glass.purchase.constant.PurchaseErrorCode;
import com.ruibang.glass.purchase.domain.req.PurchaseApplyReq;
import com.ruibang.glass.purchase.dto.ApplyManageDTO;
import com.ruibang.glass.purchase.dto.SelectDTO;
import com.ruibang.glass.purchase.entity.PurchaseApplyManage;
import com.ruibang.glass.purchase.mapper.PurchaseApplyManageMapper;
import com.ruibang.glass.purchase.service.PurchaseApplyManageService;
import com.teaming.cloud.framework2.common.exception.ServiceException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 供应商类别服务实现类
 * </p>
 *
 * @author mameng
 * @since 2024-03-29
 */
@Service
public class PurchaseApplyManageServiceImpl extends ServiceImpl<PurchaseApplyManageMapper, PurchaseApplyManage> implements PurchaseApplyManageService {
    /**
     * 新增
     *
     * @param areaManage
     */
    @Override
    public void addChild(PurchaseApplyManage areaManage) {
        PurchaseApplyManage purchaseApplyManage = baseMapper.selectOne(Wrappers.<PurchaseApplyManage>lambdaQuery().eq(PurchaseApplyManage::getId, areaManage.getParentId()));
        if (purchaseApplyManage == null) {
            areaManage.setLevel(Constants.ONE_INT);
        } else {
            int level = purchaseApplyManage.getLevel() + Constants.ONE_INT;
            areaManage.setLevel(level);
        }
        baseMapper.insert(areaManage);
    }

    @Override
    public List<SelectDTO> getAreaNameList() {
        List<SelectDTO> nameList = new ArrayList<>();
        List<PurchaseApplyManage> purchaseApplyManages = baseMapper.selectList(Wrappers.<PurchaseApplyManage>lambdaQuery().isNotNull(PurchaseApplyManage::getId));
        for (PurchaseApplyManage purchaseApplyManage : purchaseApplyManages) {
            SelectDTO selectDTO = new SelectDTO();
            selectDTO.setLabel(purchaseApplyManage.getApplyName());
            selectDTO.setValue(purchaseApplyManage.getId());
            nameList.add(selectDTO);
        }
        return nameList;
    }

    @Override
    public void removePurchaseApplyManage(String id) {
        List<PurchaseApplyManage> purchaseApplyManages = baseMapper.selectList(Wrappers.<PurchaseApplyManage>lambdaQuery().eq(PurchaseApplyManage::getParentId, id));
        if (purchaseApplyManages.size() > 0) {
            throw new ServiceException(PurchaseErrorCode.NOT_REMOVE_APPLY_NAME.getCode(), PurchaseErrorCode.NOT_REMOVE_APPLY_NAME.getMsg());
        }
        baseMapper.deleteById(id);
    }

    @Override
    public void editChild(PurchaseApplyManage purchaseApplyManage) {
        PurchaseApplyManage purchaseApplyManage1 = baseMapper.selectById(purchaseApplyManage.getId());
        purchaseApplyManage1.setApplyName(purchaseApplyManage.getApplyName());
        baseMapper.updateById(purchaseApplyManage1);
    }

    /**
     * 供应商全表
     *
     * @param purchaseApplyReq
     * @return
     */

    @Override
    public List<ApplyManageDTO> queryApplyManageDTOList(PurchaseApplyReq purchaseApplyReq) {
        List<PurchaseApplyManage> areaManages = baseMapper.selectList(Wrappers.<PurchaseApplyManage>lambdaQuery().isNotNull(PurchaseApplyManage::getId));
        if (StringUtils.isEmpty(purchaseApplyReq.getAreaName())) {
            List<PurchaseApplyManage> records = areaManages;
            List<String> parentsIdList = new ArrayList<>();
            Set<ApplyManageDTO> areaManageDTOS = new HashSet<>();
            for (PurchaseApplyManage areaManage : records) {
                ApplyManageDTO areaManageDTO = new ApplyManageDTO();
                areaManageDTO.setId(areaManage.getId());
                areaManageDTO.setApplyName(areaManage.getApplyName());
                areaManageDTO.setParentId(areaManage.getParentId());
                areaManageDTO.setLevel(areaManage.getLevel());
                areaManageDTOS.add(areaManageDTO);
            }
            parentsIdList = records.stream().map(PurchaseApplyManage::getId).collect(Collectors.toList());
            getAllChidList(areaManageDTOS, areaManages, parentsIdList);
            List<ApplyManageDTO> areaManageDTOS1 = cleanSource(areaManageDTOS);
            IPage<ApplyManageDTO> areaManageDTOIPage = new Page<>();
            areaManageDTOIPage.setRecords(areaManageDTOS1);
            return areaManageDTOS1;
        }
        List<PurchaseApplyManage> areaManages1 = baseMapper.selectList(Wrappers.<PurchaseApplyManage>lambdaQuery().like(PurchaseApplyManage::getApplyName, purchaseApplyReq.getAreaName()));
        List<String> areaIdList = areaManages1.stream().map(PurchaseApplyManage::getId).collect(Collectors.toList());
        Set<ApplyManageDTO> areaManageDTOS = new HashSet<>();
        getAllParentList(areaManageDTOS, areaManages, areaIdList);
        List<ApplyManageDTO> areaManageDTOS1 = cleanSource(areaManageDTOS);
        return areaManageDTOS1;
    }

    /**
     * 父层级获取所有子层级
     *
     * @param areaManageDTOS
     * @param allAreaManages
     * @param parentsIdList
     */
    public void getAllChidList(Set<ApplyManageDTO> areaManageDTOS, List<PurchaseApplyManage> allAreaManages, List<String> parentsIdList) {
        Set<ApplyManageDTO> newList = new HashSet<>();
        for (PurchaseApplyManage areaManage : allAreaManages) {
            for (String id : parentsIdList) {
                if (areaManage.getParentId().equals(id)) {
                    ApplyManageDTO areaManageDTO = new ApplyManageDTO();
                    areaManageDTO.setId(areaManage.getId());
                    areaManageDTO.setApplyName(areaManage.getApplyName());
                    areaManageDTO.setParentId(areaManage.getParentId());
                    areaManageDTO.setLevel(areaManage.getLevel());
                    newList.add(areaManageDTO);
                }
            }
        }
        if (CollectionUtils.isEmpty(newList)) {
            return;
        }
        areaManageDTOS.addAll(newList);
        List<String> collect = newList.stream().map(ApplyManageDTO::getId).collect(Collectors.toList());
        getAllChidList(areaManageDTOS, allAreaManages, collect);
    }

    /**
     * 数据组装
     *
     * @param areaManageDTOS
     * @return
     */
    private List<ApplyManageDTO> cleanSource(Set<ApplyManageDTO> areaManageDTOS) {
        Map<Integer, List<ApplyManageDTO>> areaMap = areaManageDTOS.stream().sorted(Comparator.comparing(ApplyManageDTO::getLevel)).collect(Collectors.groupingBy(ApplyManageDTO::getLevel));
        List<Integer> levelList = areaManageDTOS.stream().sorted(Comparator.comparing(ApplyManageDTO::getLevel).reversed()).map(ApplyManageDTO::getLevel).distinct().collect(Collectors.toList());
        List<ApplyManageDTO> levelAllList = new ArrayList<>();
        for (Integer level : levelList) {
            List<ApplyManageDTO> levelOneList = areaMap.get(level);
            if (CollectionUtil.isEmpty(levelAllList)) {
                levelAllList.addAll(levelOneList);
            } else {
                for (ApplyManageDTO areaManageDTO : levelOneList) {
                    for (ApplyManageDTO manageDTO : levelAllList) {
                        if (areaManageDTO.getId().equals(manageDTO.getParentId())) {
                            if (CollectionUtils.isEmpty(areaManageDTO.getChildren())) {
                                List<ApplyManageDTO> addChidren = new ArrayList<>();
                                addChidren.add(manageDTO);
                                areaManageDTO.setChildren(addChidren);
                            } else {
                                List<ApplyManageDTO> addChidren = areaManageDTO.getChildren();
                                addChidren.add(manageDTO);
                                areaManageDTO.setChildren(addChidren);
                            }
                        }
                    }
                }
                levelAllList = new ArrayList<>();
                levelAllList.addAll(levelOneList);
            }
        }
        return levelAllList;
    }

    public void getAllParentList(Set<ApplyManageDTO> areaManageDTOS, List<PurchaseApplyManage> allAreaManages, List<String> idList) {
        List<String> nextId = new ArrayList<>();
        for (PurchaseApplyManage areaManage : allAreaManages) {
            for (String id : idList) {
                if (id.equals(areaManage.getId()) && areaManage.getLevel() == 1) {
                    ApplyManageDTO areaManageDTO = new ApplyManageDTO();
                    areaManageDTO.setId(areaManage.getId());
                    areaManageDTO.setApplyName(areaManage.getApplyName());
                    areaManageDTO.setParentId(areaManage.getParentId());
                    areaManageDTO.setLevel(areaManage.getLevel());
                    areaManageDTOS.add(areaManageDTO);
                }
                if (id.equals(areaManage.getId()) && areaManage.getLevel() != 1) {
                    ApplyManageDTO areaManageDTO = new ApplyManageDTO();
                    areaManageDTO.setId(areaManage.getId());
                    areaManageDTO.setApplyName(areaManage.getApplyName());
                    areaManageDTO.setParentId(areaManage.getParentId());
                    areaManageDTO.setLevel(areaManage.getLevel());
                    areaManageDTOS.add(areaManageDTO);
                    nextId.add(areaManage.getParentId());
                }
            }

        }
        if (CollectionUtils.isEmpty(nextId)) {
            return;
        } else {
            getAllParentList(areaManageDTOS, allAreaManages, nextId);
        }

    }
}
